package com.example.demo.juc;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

public class AlternatePrintTest {

    //使用wait/notify打印ABC
//    private int num;
//
//    private static final Object lock = new Object();
//
//    private void printABC(int targetNum){
//        for (int i = 0; i < 10; i++) {
//            synchronized (lock){
//                //这个while其实是用来筛选线程的，只有num % 3 == targetNum的线程才能执行while方法后面的内容，其他的都被释放重新请求锁去了
////                当线程被唤醒后，可能if()中的条件已经不满足了，出现虚假唤醒。因此在while()中使用wait()
//                while(num % 3 != targetNum){
//                    try {
//                        lock.wait();
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                }
//                num++;
//                System.out.println(Thread.currentThread().getName());
//                lock.notifyAll();
//            }
//        }
//    }
//
//    public static void main(String[] args) {
//        AlternatePrintTest test = new AlternatePrintTest();
//        new Thread(()->test.printABC(0), "A").start();
//        new Thread(()->test.printABC(1), "B").start();
//        new Thread(()->test.printABC(2), "C").start();
//    }





    //使用Lock打印ABC
//    private int num;
//    private Lock lock = new ReentrantLock();
//
//    public void printABC(int targetNum){
//        for (int i = 0; i < 10;) {
//            lock.lock();
//            if(num % 3 == targetNum){
//                num++;
//                i++;
//                System.out.println(Thread.currentThread().getName());
//            }
//            lock.unlock();
//        }
//    }
//
//    public static void main(String[] args) {
//        AlternatePrintTest test = new AlternatePrintTest();
//        new Thread(()->test.printABC(0), "A").start();
//        new Thread(()->test.printABC(1), "B").start();
//        new Thread(()->test.printABC(2), "C").start();
//    }



    //交替打印奇偶数
//    private volatile int num;
//    private Object monitor = new Object();
//
//    AlternatePrintTest(int num){
//        this.num = num;
//    }
//
//    public void printABC(){
//            synchronized (monitor){
//                while(num<10){
//                    try {
//                        System.out.println(Thread.currentThread().getName());
//                        System.out.println(++num);
//                        monitor.notifyAll();
//                        monitor.wait();
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                }
//                monitor.notifyAll();
//            }
//    }
//
//    public static void main(String[] args) throws InterruptedException {
//        AlternatePrintTest test = new AlternatePrintTest(0);
//        new Thread(()->test.printABC(), "A").start();
//        Thread.sleep(1000);
//        new Thread(()->test.printABC(), "B").start();
//    }

    //n个线程循环打印1-100
//    private volatile Integer num;
//    private Object lock = new Object();
//
//    AlternatePrintTest(int num){
//        this.num = num;
//    }
//
//    public void PrintABC(int target){
//        for (int i = 0; i < 100; i++) {
//            synchronized (lock){
//                while(num%3 != target){
//                    if(num>100){
//                        break;
//                    }
//                    try {
//                        lock.wait();
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                }
//                if(num>100){
//                    break;
//                }
//                System.out.println(Thread.currentThread().getName()+ ":" + num);
//                num++;
//                lock.notifyAll();
//            }
//        }
//    }
//
//    public static void main(String[] args) {
//        AlternatePrintTest test = new AlternatePrintTest(0);
//
//        new Thread(()->{
//            test.PrintABC(0);
//        },"A").start();
//
//        new Thread(()->{
//            test.PrintABC(1);
//        },"B").start();
//
//        new Thread(()->{
//            test.PrintABC(2);
//        },"C").start();
//    }



    //用两个线程，一个输出字母，一个输出数字，交替输出 1A2B3C4D...26Z
//    private static Thread firstThread,secondThread;
//
//    public static void main(String[] args) {
//        firstThread = new Thread(()->{
//            for (int i = 0; i < 26; i++) {
//                System.out.println((char)('A'+i));
//                LockSupport.unpark(secondThread);
//                LockSupport.park();
//            }
//        },"firstThread");
//
//        secondThread = new Thread(()->{
//            for (int i = 0; i < 26; i++) {
//                System.out.println(i);
//                LockSupport.unpark(firstThread);
//                LockSupport.park();
//            }
//        },"secondThread");
//
//        secondThread.start();
//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
//        firstThread.start();
//    }

//多线程按顺序调用，A->B->C，AA 打印 5 次，BB 打印10 次，CC 打印 15 次，重复 10 次

//    private int num;
//    AlternatePrintTest(int num){
//        this.num = num;
//    }
//
//    private static Lock lock = new ReentrantLock();
//    private static Condition c1 = lock.newCondition();
//    private static Condition c2 = lock.newCondition();
//    private static Condition c3 = lock.newCondition();
//
//    public void printABC(int target,Condition cur,Condition next){
//        for (int i = 0; i < 10; i++) {
//            lock.lock();
//            try {
//                while(num%3!=target){
//                    cur.await();
//                }
//                num++;
//                for (int j = 0; j < (target+1)*5; j++) {
//                    System.out.println(Thread.currentThread().getName());
//                }
//                next.signal();
//            }catch (Exception e){
//                e.printStackTrace();
//            }finally {
//                lock.unlock();
//            }
//        }
//    }
//
//    public static void main(String[] args) throws InterruptedException {
//        AlternatePrintTest test = new AlternatePrintTest(0);
//        new Thread(()->{
//            test.printABC(0,c1,c2);
//        },"AA").start();
//        Thread.sleep(500);
//
//        new Thread(()->{
//            test.printABC(1,c2,c3);
//        },"BB").start();
//        Thread.sleep(500);
//
//        new Thread(()->{
//            test.printABC(2,c3,c1);
//        },"CC").start();
//    }





}
